##############################################################################
#
# Just Another Package Builder http://code.google.com/p/japb
# (c)2011 Alexander Galanin
#
# Functions for operating with file nodes.
#
# Each file node is a tuple of two elements: path to file on file system and
# file name.
#
# File nodes handling looks like handling of files on the file system: nodes
# can be copied to directory, renamed etc. The main advantage of file nodes is
# preserving of file names during these operations.
#
# All generated file nodes are placed under temporary directory. Each file
# name is prefixed with number to avoid name collisions.
#
# Auto-conversion of ordinary files to file-nodes is allowed, but file should
# not look like Tcl list.
#
# $Id$
#
##############################################################################

package require Tcl 8.5

package provide japb::filenode 1.0

namespace eval japb {

namespace export filenode

namespace eval filenode {

# Counter for auto-generated files
variable count 0

# Create file node from file that already exists
# @param path path to file
# @param name new file name. if not specified, path will be used instead
# @return file node
proc create {path {name {}}} {
    variable [namespace parent]::baseDir

    if {$name eq ""} {
        set name $path
    }
    list [file join $baseDir $path] $name
}

# Query path component from file node
# @return file path
proc path {filenode} {
    lindex $filenode 0
}

# Query name component from file node
# @return file name
proc name {filenode} {
    set res [lindex $filenode 1]
    if {$res eq ""} {
        set res [path $filenode]
    }
    return $res
}

# Create a temporary directory
# @return new directory node
proc mkdir {dirname} {
    variable [namespace parent]::tempDir

    set path [file join $tempDir [id].[file tail $dirname]]
    file mkdir $path
    create $path $dirname
}

# Create a temporary file
# @return new file node
proc mkfile {filename} {
    variable [namespace parent]::tempDir

    create [file join $tempDir [id].[file tail $filename]] $filename
}

# Copy file node to a directory node. New file will be placed into directory
# using it's original name as relative path.
# @param filenode file node to copy
# @param dirnode directory not to copy into
# @return detination file node
proc copyToDir {filenode dirnode} {
    set destpath [path $dirnode]/[name $filenode]
    file mkdir [file dirname $destpath]
    file copy [path $filenode] $destpath
    create $destpath [name $filenode]
}

# Change file node name field
# @param filenode file node
# @param newName new node name
# @return renamed node
proc rename {filenode newName} {
    create [path $filenode] $newName
}

# Generate new unique ID to avoid name conflicts
proc id {} {
    variable count
    format %04d [incr count]
}

namespace export \
    create \
    path \
    name \
    mkdir \
    mkfile \
    copyToDir \
    rename
namespace ensemble create
}

}

